package onez.project.core;

import onez.project.core.netty.NettyHttpClient;
import onez.project.core.netty.NettyHttpServer;
import onez.project.core.netty.processor.DisruptorNettyCoreProcessor;
import onez.project.core.netty.processor.NettyCoreProcessor;
import onez.project.core.netty.processor.NettyProcessor;
import lombok.extern.slf4j.Slf4j;

import static onez.project.common.constant.GatewayConst.BUFFER_TYPE_PARALLEL;

/**
 * Container类是系统的核心容器，负责初始化和管理Netty HTTP服务器、客户端以及处理器的生命周期。
 * 它根据配置信息决定是否使用Disruptor来提高性能，并确保各个组件按照正确的顺序启动和关闭。
 */
@Slf4j
public class Container implements LifeCycle {
    private final Config config;

    private NettyHttpServer nettyHttpServer;

    private NettyHttpClient nettyHttpClient;

    private NettyProcessor nettyProcessor;

    /**
     * 构造函数，接收配置信息并初始化容器。
     *
     * @param config 系统的配置信息
     */
    public Container(Config config) {
        this.config = config;
        init();
    }

    /**
     * 初始化方法，根据配置信息初始化Netty处理器、HTTP服务器和客户端。
     * 如果配置了并行缓冲区类型，则使用DisruptorNettyCoreProcessor，否则仅使用NettyCoreProcessor。
     */
    @Override
    public void init() {
        NettyCoreProcessor nettyCoreProcessor = new NettyCoreProcessor();
        //如果启动要使用多生产者多消费组 那么我们读取配置
        if (BUFFER_TYPE_PARALLEL.equals(config.getParallelBufferType())) {
            //开启配置的情况下使用Disruptor
            this.nettyProcessor = new DisruptorNettyCoreProcessor(config, nettyCoreProcessor);
        } else {
            this.nettyProcessor = nettyCoreProcessor;
        }

        this.nettyHttpServer = new NettyHttpServer(config, nettyProcessor);

        this.nettyHttpClient = new NettyHttpClient(config, nettyHttpServer.getEventLoopGroupWorker());
    }

    /**
     * 启动方法，按照正确的顺序启动Netty处理器、HTTP服务器和客户端，
     * 并在启动完成后记录日志信息。
     */
    @Override
    public void start() {
        nettyProcessor.start();
        nettyHttpServer.start();
        nettyHttpClient.start();
        log.info("gateway started!");
    }

    /**
     * 关闭方法，按照正确的顺序关闭Netty处理器、HTTP服务器和客户端，
     * 以确保资源被正确释放。
     */
    @Override
    public void shutdown() {
        nettyProcessor.shutDown();
        nettyHttpServer.shutdown();
        nettyHttpClient.shutdown();
    }
}
